package serverClientDemo;

import java.awt.BorderLayout;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Observable;
import java.util.Observer;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SpringLayout;
import javax.swing.UIManager;

/**
 * A GUI interface for Client
 * 
 * @author Chris
 */
public class ClientGuiInterface extends JFrame implements Observer, KeyListener {

	private static final long serialVersionUID = 5470321449615096464L;
	Client client;
	JTextField addressField, portField, messageField, socketPortField;
	JLabel portLabel;
	JTextArea textArea;

	/**
	 * Creates a ClientGuiInterface
	 */
	public ClientGuiInterface() {
		client = new Client();
		client.addObserver(this);
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
	}

	/**
	 * Creates and shows the gui
	 */
	private void createAndShowGui() {

		JLabel label;

		// frame parameters
		this.setSize(300, 400);
		this.setLocationRelativeTo(null);
		this.setResizable(false);

		// create main panel
		JPanel mainPanel = new JPanel();
		this.getContentPane().add(mainPanel);
		mainPanel.setLayout(new BorderLayout());

		// create address panel
		JPanel addressPanel = new JPanel(new SpringLayout());

		label = new JLabel("server address");
		addressPanel.add(label);
		addressField = new JTextField();
		addressPanel.add(addressField);

		label = new JLabel("server listening port");
		addressPanel.add(label);
		portField = new JTextField();
		addressPanel.add(portField);

		label = new JLabel("client socket port");
		addressPanel.add(label);
		socketPortField = new JTextField();
		addressPanel.add(socketPortField);
		socketPortField.setName("socketPort");
		socketPortField.addKeyListener(this);

		// create client socket port display
		label = new JLabel("client port :");
		addressPanel.add(label);
		portLabel = new JLabel(new Integer(client.getPort()).toString());
		addressPanel.add(portLabel);

		int borderspace = 2;
		SpringUtilities.makeCompactGrid(addressPanel, 4, 2, borderspace,
				borderspace, borderspace, borderspace);
		mainPanel.add(addressPanel, BorderLayout.PAGE_START);

		// create text area
		textArea = new JTextArea();
		JScrollPane scrollPane = new JScrollPane(textArea);
		textArea.setEditable(false);
		String text = "";
		textArea.setText(text);
		mainPanel.add(scrollPane, BorderLayout.CENTER);
		scrollPane
				.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

		// create message field
		messageField = new JTextField();
		mainPanel.add(messageField, BorderLayout.PAGE_END);
		messageField.setName("messageField");
		messageField.addKeyListener(this);

		// set visible
		this.setVisible(true);
		textArea.setText(text);

	}

	/**
	 * Main
	 * 
	 * @param args
	 *            unused
	 */
	public static void main(String args[]) {
		// set look and feel
		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (Exception e) {
			e.printStackTrace();
		}
		ClientGuiInterface gui = new ClientGuiInterface();
		gui.createAndShowGui();
	}

	/**
	 * Get updates from the client
	 */
	@Override
	public void update(Observable o, Object arg) {
		if (arg instanceof String) {
			String message = (String) arg;
			textArea.append("received: " + message + '\n');
			textArea.setCaretPosition(textArea.getText().length());
		}
	}

	/**
	 * Handle key presses
	 */
	@Override
	public void keyPressed(KeyEvent event) {
		Object source = event.getSource();
		if (source instanceof JTextField) {
			JTextField textField = (JTextField) source;
			String name = textField.getName();
			if (name.equals("messageField")) {
				int key = event.getKeyCode();
				if (key == KeyEvent.VK_ENTER) {
					portLabel.setText(new Integer(client.getPort()).toString());
					if (client.sendMessage(addressField.getText(), Integer
							.parseInt(portField.getText()), messageField
							.getText())) {
						textArea.append("sent: " + messageField.getText()
								+ '\n');
						messageField.setText("");
					}
				}
			}
		}
	}

	/**
	 * Handle key releases
	 */
	@Override
	public void keyReleased(KeyEvent event) {
		Object source = event.getSource();
		if (source instanceof JTextField) {
			JTextField textField = (JTextField) source;
			String name = textField.getName();
			if (name.equals("socketPort")) {
				try {
					int port = Integer.parseInt(socketPortField.getText());
					client.setPort(port);
					portLabel.setText(new Integer(client.getPort()).toString());
				} catch (Exception e) {
					return;
				}
			}
		}
	}

	/**
	 * Handle keys typed
	 */
	@Override
	public void keyTyped(KeyEvent e) {
		// do nothing
	}

}
